﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace EstateNuke.Data
{
    public partial class CustomerRequirement
    {
        #region Fileds & Properties

        /// <summary>
        /// </summary>
        internal IList<CustomerRequirementResistance> CustomerRequirementResistances
        {
            get
            {
                return InternalCustomerRequirementResistances.Where(customerRequirementResistance => customerRequirementResistance.IsDeleted == false).ToList();
            }
        }

        /// <summary>
        /// </summary>
        public IList<Resistance> Resistances
        {
            get
            {
                return InternalCustomerRequirementResistances.Where(customerRequirementResistance => customerRequirementResistance.IsDeleted == false && customerRequirementResistance.Resistance.IsDeleted == false).Select(customerRequirementResistance => customerRequirementResistance.Resistance).ToList();
            }
        }

        /// <summary>
        /// </summary>
        internal IList<CustomerRequirementRoomType> CustomerRequirementRoomTypes
        {
            get
            {
                return InternalCustomerRequirementRoomTypes.Where(customerRequirementRoomType => customerRequirementRoomType.IsDeleted == false).ToList();
            }
        }

        /// <summary>
        /// </summary>
        public IList<RoomType> RoomTypes
        {
            get
            {
                return InternalCustomerRequirementRoomTypes.Where(customerRequirementRoomType => customerRequirementRoomType.IsDeleted == false && customerRequirementRoomType.RoomType.IsDeleted == false).Select(customerRequirementRoomType => customerRequirementRoomType.RoomType).ToList();
            }
        }

        #endregion

        #region Add & Remove CustomerRequirementResistance

        /// <summary>
        /// </summary>
        /// <returns></returns>
        internal CustomerRequirementResistance AddCustomerRequirementResistance(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            var customerRequirementResistance = new CustomerRequirementResistance
                                                    {
                                                        RowId = Guid.NewGuid(),
                                                        CreatedDate = DateTime.Now,
                                                    };
            InternalCustomerRequirementResistances.Add(customerRequirementResistance);
            customerRequirementResistance.IsDeleted = false;
            customerRequirementResistance.ModifiedDate = DateTime.Now;
            customerRequirementResistance.ModifiedByUser = modifiedUser;
            return customerRequirementResistance;
        }

        /// <summary>
        /// </summary>
        /// <param name = "customerRequirementResistance"></param>
        /// <param name = "modifiedUser"></param>
        internal void RemoveCustomerRequirementResistance(CustomerRequirementResistance customerRequirementResistance, User modifiedUser)
        {
            if (customerRequirementResistance == null)
            {
                throw new ArgumentNullException("customerRequirementResistance");
            }
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (InternalCustomerRequirementResistances.Contains(customerRequirementResistance))
            {
                customerRequirementResistance.Delete(modifiedUser);
            }
        }

        #endregion

        #region Set Resistances

        /// <summary>
        /// </summary>
        /// <param name = "resistances"></param>
        /// <param name = "modifiedUser"></param>
        public void SetResistances(IList<Resistance> resistances, User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (resistances != null)
            {
                var customerRequirementResistances = InternalCustomerRequirementResistances.ToList();
                customerRequirementResistances.ForEach(customerRequirementResistance => customerRequirementResistance.Delete(modifiedUser));
                foreach (var resistance in resistances.Distinct())
                {
                    var currentCustomerRequirementResistance = customerRequirementResistances.FirstOrDefault(customerRequirementResistance => customerRequirementResistance.Resistance == resistance);
                    if (currentCustomerRequirementResistance != null)
                    {
                        currentCustomerRequirementResistance.CancelDelete(modifiedUser);
                    }
                    else
                    {
                        currentCustomerRequirementResistance = AddCustomerRequirementResistance(modifiedUser);
                        currentCustomerRequirementResistance.Resistance = resistance;
                    }
                }
            }
        }

        #endregion

        #region Add & Remove CustomerRequirementRoomType

        /// <summary>
        /// </summary>
        /// <returns></returns>
        internal CustomerRequirementRoomType AddCustomerRequirementRoomType(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            var customerRequirementRoomType = new CustomerRequirementRoomType
                                                  {
                                                      RowId = Guid.NewGuid(),
                                                      CreatedDate = DateTime.Now,
                                                  };
            InternalCustomerRequirementRoomTypes.Add(customerRequirementRoomType);
            customerRequirementRoomType.IsDeleted = false;
            customerRequirementRoomType.ModifiedDate = DateTime.Now;
            customerRequirementRoomType.ModifiedByUser = modifiedUser;
            return customerRequirementRoomType;
        }

        /// <summary>
        /// </summary>
        /// <param name = "customerRequirementRoomType"></param>
        /// <param name = "modifiedUser"></param>
        internal void RemoveCustomerRequirementRoomType(CustomerRequirementRoomType customerRequirementRoomType, User modifiedUser)
        {
            if (customerRequirementRoomType == null)
            {
                throw new ArgumentNullException("customerRequirementRoomType");
            }
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (InternalCustomerRequirementRoomTypes.Contains(customerRequirementRoomType))
            {
                customerRequirementRoomType.Delete(modifiedUser);
            }
        }

        #endregion

        #region Set RoomTypes

        /// <summary>
        /// </summary>
        /// <param name = "roomTypes"></param>
        /// <param name = "modifiedUser"></param>
        public void SetRoomTypes(IList<RoomType> roomTypes, User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (roomTypes != null)
            {
                var customerRequirementRoomTypes = InternalCustomerRequirementRoomTypes.ToList();
                customerRequirementRoomTypes.ForEach(customerRequirementRoomType => customerRequirementRoomType.Delete(modifiedUser));
                foreach (var roomType in roomTypes.Distinct())
                {
                    var currentCustomerRequirementRoomType = customerRequirementRoomTypes.FirstOrDefault(customerRequirementRoomType => customerRequirementRoomType.RoomType == roomType);
                    if (currentCustomerRequirementRoomType != null)
                    {
                        currentCustomerRequirementRoomType.CancelDelete(modifiedUser);
                    }
                    else
                    {
                        currentCustomerRequirementRoomType = AddCustomerRequirementRoomType(modifiedUser);
                        currentCustomerRequirementRoomType.RoomType = roomType;
                    }
                }
            }
        }

        #endregion

        #region Ensure

        /// <summary>
        /// </summary>
        public void Ensure()
        {
            Comment = string.IsNullOrEmpty(Comment) ? null : Comment.Length > 512 ? Comment.Substring(0, 512) : Comment;
        }

        #endregion

        #region Delete

        /// <summary>
        /// </summary>
        public void Delete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = true;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
            ((List<CustomerRequirementResistance>) CustomerRequirementResistances).ForEach(customerRequirementResistance => customerRequirementResistance.Delete(modifiedUser));
            ((List<CustomerRequirementRoomType>) CustomerRequirementRoomTypes).ForEach(customerRequirementRoomType => customerRequirementRoomType.Delete(modifiedUser));
        }

        /// <summary>
        /// </summary>
        public void CancelDelete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = false;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        #endregion
    }
}